import random
import math
import os
from genemid_ins import *

# path = f'/Users/liuchangkundeimac/real-time-scheduling/file_test/test0/' + 'ann2.log'
# f = open(path,'w')
def lcm(x, y): 
   #  获取最大的数
    if x > y:
        greater = x
    else:
        greater = y
 
    while(True):
        if((greater % x == 0) and (greater % y == 0)):
            lcm = greater
            break
        greater += 1
    return lcm

def Lcm_list(task_set):
    t = 1
    for i in range(len(task_set)):
        t = lcm(t,task_set[i].getPeriod())
    return t
   
def DBF_C(task_set,t,d_set):
    sum = 0
    for i in range(len(task_set)):
        c_i = task_set[i].getComcost()
        p_i = task_set[i].getPeriod()
        D_i = task_set[i].getDDL()
        d_i = d_set[i]
        sum += c_i*(math.floor((t+d_i-D_i)/p_i) + 1)
    return sum
    
def DBF_B(task_set,t,d_set):
    sum = 0
    for i in range(len(task_set)):
        r_i = task_set[i].getUpcost()
        p_i = task_set[i].getPeriod()
        d_i = d_set[i]
        sum += r_i*(math.floor((t-d_i)/p_i) + 1)
    return sum

def cal_reward(t,s1,s2):
    reward = 0
    if(t-s1>=0 and t-s2>=0):
        reward = 1
    else:
        reward = -1
    return reward

# def reward_func(t_list,task_set,d_set):
#     total_reward = 0
#     for i in range(len(t_list)):
#         t = t_list[i]
#         s1 = DBF_C(task_set,t,d_set)
#         s2 = DBF_B(task_set,t,d_set)
#         if(cal_reward(t_list[i],s1,s2) == 1):
#             total_reward += cal_reward(t_list[i],s1,s2)
#         else:
#             total_reward += 0
#     return total_reward

def reward_func(until,task_set,d_set,file_name):
    for i in range(len(task_set)):
        t_i = task_set[i]
        mddl = d_set[i]
        t_i.mid_deadline = mddl
    result,number = MidSimuAnn(task_set,until,0,file_name)
    return result,number

def Ini_dset(task_set):
    dset = []
    for i in range(len(task_set)):
        r_i = task_set[i].getUpcost()
        c_i = task_set[i].getComcost()
        D_i = task_set[i].getDDL()
        dset.append(D_i)
    return dset

def time_list(t):
    t_list = []
    for i in range(t):
        t_list.append(i+1)
    return t_list

def Channel_uti(task_set):
    u = 0
    for i in range(len(task_set)):
        t_i = task_set[i]
        r_i = t_i.getUpcost()
        p_i = t_i.getPeriod()
        u += r_i/p_i
    return u

def New_dset(task_set):
    dset = []
    for i in range(len(task_set)):
        r_i = task_set[i].getUpcost()
        c_i = task_set[i].getComcost()
        D_i = task_set[i].getDDL()
        d_i = random.randint(r_i,D_i-c_i)
        dset.append(d_i)
    return dset

def SimuAnnMid(task_set,file_name):
    path = file_name + 'ann_mid.log'
    f = open(path,'a')
    itr = 500
    U_C = Channel_uti(task_set)
    print("Channel utilization of the task set: ",U_C,file=f)
    d_set = Ini_dset(task_set)
    print("Initial dset:",d_set,file=f)
    until = Lcm_list(task_set)
    print("t_max:",until,file=f)
    until = 20000
    # if until >= 20000:
    #     until = 20000
    # else:
    #     until = until
    # t_list = time_list(t_max)
    # if(len(t_list) >= 40000):
    #     #t_sample = random.sample(t_list,20000)
    #     t_sample = t_list[:20000]
    #     y = [reward_func(t_sample,task_set,d_set),reward_func(random.sample(t_list[:20000],10000),task_set,d_set)] 
    # else:
    #     t_sample = t_list
    y,number = reward_func(until,task_set,d_set,file_name)
    print("job number is:",number,file=f)
    print("initial finished jobs is:",y,file=f)
    if y == number:
        stop = 1
    else:
        stop = 0
    best_d_set = d_set
    y_best = y
    for i in range(itr):
        stop = 0
        new_d_set = New_dset(task_set)
        print("---------------------------------------------",file=f)
        print("New_dset after check:",new_d_set,file=f)
        # if(len(t_list) >= 40000):
        #     y_new = [reward_func(t_sample,task_set,new_d_set),reward_func(random.sample(t_list[:20000],10000),task_set,d_set)]
        # else:
        #     y_new = [reward_func(t_sample,task_set,new_d_set)]
        y_new,number = reward_func(until,task_set,new_d_set,file_name)
        print("Reward:",y,file=f)
        print("New reward:",y_new,file=f)
        # if y_new > y  or math.exp(-abs(y_new - y) / T > random.random()):
        if y_new > y_best:  
            print("New value get",file=f)
            best_d_set = new_d_set
            y_best = y_new
            print("Best_d_set:",best_d_set,file=f)

        if y_new == number:
            stop = 1
            break
        
        

    print("Final result:",best_d_set,file=f)
    if stop == 1:
        y_final,number = reward_func(until,task_set,best_d_set,file_name)
        if(y_final == number):
            print("The task set is totally feasible",file=f)
        else:
            print("This task set is schedulable in the vast majority of cases.",file=f)
    else:
        print("The task set is not feasible",file=f)
    
    return d_set,until